﻿/*
 *Author: Jeff Liu 
 *
 *Under MIT License
 *jebberwocky@gmail.com
 *
 * Notice: this is only a "simple" program to demostrate how to use Google Geo Kit. It is not perfomance turned nor code refined
 * for any furthur question, please mail to jebberwocky@gmail.com, glad to answer your question
 */

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using CtpGglGeo.Core;
using CtpGglGeo.Ggl;
using CtpGglGeo.Const;
using CtpGglMap.Impl;
using CtpGglMap.Windows.Control;
using CtpGglMap.Plus;
using CtpGglMap;
using CtpGgglMapWinUI.Cache;
using Citiport.Demo.Cache;
using CtpGglMap.Util;

namespace windowsComponent
{
    public partial class Form2 : Form
    {
        //CtpGglMap.Impl.StaticGMap gmap;

        CtpGglMap.Plus.StaticGMapPlus gmap;

        IMapImageCache imagecache = AppMapCache.Instance;

        public Form2()
        {
            InitializeComponent();
            
            // reverse geocoding
            SpotInfo sinfo = new SpotInfo();
            sinfo.Address = "New York";
            Geocoder geo = new Geocoder();
            GeoResult result = geo.GetGeoResult(sinfo);
            if (GeoResultStatus.OK.Equals(result.Status))
            {
                foreach (GeoObj obj in result.Results)
                {
                    this.textBox2.Text = obj.FormattedAddress + "(" + obj.Geometry.Location.Lat + "," + obj.Geometry.Location.Lng + ")";
                }
            }

            //gmap = new CtpGglMap.Impl.StaticGMap();
            gmap = new StaticGMapPlus();
            gmap.Center = new GeoPointImpl(40.714728, -73.998672);
            gmap.Zoom = 14;
            //gmap.Cluster = new DistanceCluster(10.0);
            gmap.Height = 666;
            gmap.Width = 922;
            gmap.Sensor = false;
            //gmap.AutoFit = true;
            //gmap.ShowMarkersPath = true;
            gmap.MarkersPathColor = "0xff0000ff";
            gmap.MarkersPathWeight = "2";
            //gmap.ZoomDelta = -6;

            //markers
            GMarker markj = new GMarker() { Point = new GeoPointImpl(40.714728, -73.998672), Label = "J" };
            markj.SetMap(gmap);

            GMarker markm = new GMarker() { Point = new GeoPointImpl(40.724728, -73.898672), Label = "M" };
            markm.SetMap(gmap);

            GMarker marke = new GMarker() { Point = new GeoPointImpl(40.715748, -73.996672), Label = "E" };
            marke.SetMap(gmap);

            GMarker markf = new GMarker() { Point = new GeoPointImpl(40.714728, -73.994672), Label = "F" };
            markf.SetMap(gmap);

            GMarker markf2 = new GMarker() { Point = new GeoPointImpl(40.715748, -73.992672), Label = "F" };
            markf2.SetMap(gmap);

            GMarkerPlus mplus = new GMarkerPlus() { Point = new GeoPointImpl(40.715748, -73.992672), Label = "F", Title="cv" };
            mplus.SetMap(gmap);

            GMarkerDelta markdelta = new GMarkerDelta()
            {
                Point = new GeoPointImpl(40.715748, -73.992672),
                Label = "D",
                Title = "delta"
            , DeltaPixelX = 20, DeltaPixelY = 20};
            markdelta.SetMap(gmap);

            this.map.OnGMarkerClick += new GStaticMap.OnGMarkerClickDelegate(this.onClickMarker);
            this.map.OnGMapNotDefined += new GStaticMap.OnGMapNotDefinedDelegate(onMapNotDefined);
            this.map.OnGMarkerMouseOver += new GStaticMap.OnGMapMarkerMouseOverDelegate(onOverMarker);
            this.map.OnGMarkerMouseOut += new GStaticMap.OnGMapMarkerMouseOutDelegate(onOutMarker);
            this.map.OnMapDoubleClick += new GStaticMap.OnGMapDoubleClickDelegate(onMapDoubleClick);

            //gmap.Center = GeoUtil.CalculateCenterFromMapItem(gmap.GetItems());
            //gmap.Zoom = GeoUtil.ZoomToFit(gmap, gmap.GetItems(), gmap.ZoomDelta)

            this.map.MapKeyGen = new SimpleMapKeyGen();
            this.map.MapImageCache = AppMapCache.Instance;

            this.map.Gmap = gmap;
        }

        protected void onMapDoubleClick(GeoPoint goint, Point point)
        {
            this.gmap.Center = goint;
            this.gmap.AutoFit = false;
            Console.WriteLine(goint.Lat + "," + goint.Lng);
            this.map.Gmap = this.gmap;
        }

        protected void onMapNotDefined(StaticGMap map)
        {
            MessageBox.Show("Gmap is not defined");
        }

        protected void onClickMarker(GMarker marker, Point point)
        {
            /*
             * Geocoding
             */ 
            this.textBox1.Text += "Point: " + point + ", Marker Label:" + marker.Label + Environment.NewLine;
            SpotInfo sinfo = new SpotInfo();
            sinfo.LatLng = new SpotLatLng(marker.Point.Lng, marker.Point.Lat);
            Geocoder geo = new Geocoder();
            GeoResult result = geo.GetGeoResult(sinfo);
            if (GeoResultStatus.OK.Equals(result.Status))
            {
                if (result.Results.Count > 0)
                {
                    this.textBox1.Text += result.Results[0].FormattedAddress + Environment.NewLine;
                }
            }

            /*
             * Google Places
             */
            CtpGglPlaces.Core.SearchUrlParameter param = new CtpGglPlaces.Core.SearchUrlParameter();
            param.KeyProvider = new CtpGgl.API.GoogleAPIKeysProvider();
            param.Location = new CtpGglPlaces.Impl.GeoPointImpl(marker.Point.Lat, marker.Point.Lng);
            param.Radius = 500;
            param.Sensor = false;

            CtpGglPlaces.Impl.PlacesResult presult = CtpGglPlaces.Searcher.GetPlaces(param, "json");
            if (presult.Status == "OK")
            {
                List<String> placesStr = new List<string>();
                placesPairs = new Dictionary<String,String>();
                foreach (CtpGglPlaces.Impl.PlaceObj obj in presult.Results)
                {
                    placesStr.Add(obj.Name + Environment.NewLine);
                    placesPairs.Add(obj.Name.Trim(), obj.Reference.Trim());
                }
                this.lBPlaces.DataSource = placesStr;
            }
        }

        private Dictionary<String,String> placesPairs ;

        protected void onOverMarker(GMarker marker, Point point)
        {
            this.label2.Text = String.Format("{0},{1} : x:{2}, y{3}", marker.Point.Lat, marker.Point.Lng, marker.PixelXY.X, marker.PixelXY.Y);
            this.label2.Location = new Point(point.X+5, point.Y+5);
            this.label2.Show();
        }

        protected void onOutMarker()
        {
            this.label2.Hide();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            this.textBox1.Text = String.Empty;
        }

        private void linkLabel1_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
        {
            if (gmap != null)
            {
                if (gmap.AutoFit)
                    gmap.ZoomDelta = gmap.ZoomDelta - 1;
                else
                    gmap.Zoom = gmap.Zoom - 1;
                this.map.Gmap = gmap;
            }
        }

        private void linkLabel2_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
        {
            if (gmap != null)
            {
                if (gmap.AutoFit)
                    gmap.ZoomDelta = gmap.ZoomDelta + 1;
                else
                    gmap.Zoom = gmap.Zoom + 1;
                this.map.Gmap = gmap;
            }
        }

        private void lBPlaces_SelectedIndexChanged(object sender, EventArgs e)
        {
            String name = this.lBPlaces.Text.Trim();
            CtpGglPlaces.Core.DetailUrlParameter param = new CtpGglPlaces.Core.DetailUrlParameter();
            param.KeyProvider = new CtpGgl.API.GoogleAPIKeysProvider();
            param.Reference = placesPairs[name];
            param.Sensor = false;

            CtpGglPlaces.Impl.PlaceDetailsResult presult = CtpGglPlaces.Searcher.GetDetail(param, "json");
            Console.WriteLine(presult.Result.FormattedAddress);
            StringBuilder sbttext = new StringBuilder();
            sbttext.AppendLine(" -- " + presult.Result.Name + " -- "+Environment.NewLine);
            sbttext.AppendLine(" Vicinity: " + presult.Result.Vicinity);
            sbttext.AppendLine(" Phone: " + presult.Result.FormattedPhoneNumber );
            sbttext.AppendLine(" Address: " + presult.Result.FormattedAddress);
            MessageBox.Show(sbttext.ToString());
            
       }

        private void Form2_Load(object sender, EventArgs e)
        {

        } 
    }
}
